package tencent

import (
	"gitee.com/amoyx/cloud-provider/pkg/cloud/tencent/compute"
	"gitee.com/amoyx/cloud-provider/pkg/cloud/tencent/container"
	"gitee.com/amoyx/cloud-provider/pkg/cloud/tencent/database"
	"gitee.com/amoyx/cloud-provider/pkg/cloud/tencent/monitor"
	"gitee.com/amoyx/cloud-provider/pkg/cloud/tencent/network"
	"gitee.com/amoyx/cloud-provider/pkg/cloud/tencent/storage"
	"gitee.com/amoyx/cloud-provider/pkg/cloud/tencent/tse"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
	cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
	qregion "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/region/v20220627"
)

type QCloudInterface interface {
	Computes() compute.CloudComputeInterface
	Containers() container.CloudContainerInterface
	Networks() network.CloudNetworkInterface
	Databases() database.CloudDatabaseInterface
	Storages() storage.CloudStorageInterface
	TSE() tse.CloudTSEInterface
	Monitors() monitor.CloudMonitorInterface
	RegionList() (list []RegionItem, err error)
	ZoneList(region string) (list []ZoneItem, err error)
	ProductList(region string) (list []string, err error)
}

type QCloudClient struct {
	secretId   string
	secretKey  string
	credential *common.Credential
}

func NewQCloudClient(secretId string, secretKey string) QCloudInterface {
	credential := common.NewCredential(
		secretId,
		secretKey,
	)
	return &QCloudClient{
		credential: credential,
		secretId:   secretId,
		secretKey:  secretKey,
	}
}

func (q *QCloudClient) Computes() compute.CloudComputeInterface {
	return compute.NewCompute(q.Credential())
}

func (q *QCloudClient) Containers() container.CloudContainerInterface {
	return container.NewContainer(q.Credential())
}

func (q *QCloudClient) Networks() network.CloudNetworkInterface {
	return network.NewNetwork(q.Credential())
}

func (q *QCloudClient) Databases() database.CloudDatabaseInterface {
	return database.NewDatabase(q.Credential())
}

func (q *QCloudClient) Monitors() monitor.CloudMonitorInterface {
	return monitor.NewMonitor(q.Credential())
}

func (q *QCloudClient) Storages() storage.CloudStorageInterface {
	return storage.NewStorage(q.Credential())
}

func (q *QCloudClient) TSE() tse.CloudTSEInterface {
	return tse.NewTse(q.Credential())
}

func (q *QCloudClient) SecretId() string {
	return q.secretId
}

func (q *QCloudClient) SecretKey() string {
	return q.secretKey
}

func (q *QCloudClient) Credential() *common.Credential {
	return q.credential
}

func (q *QCloudClient) ProductList(region string) (list []string, err error) {
	cpf := profile.NewClientProfile()
	cpf.HttpProfile.Endpoint = "region.tencentcloudapi.com"
	client, _ := qregion.NewClient(q.Credential(), region, cpf)
	request := qregion.NewDescribeProductsRequest()
	request.Limit = common.Int64Ptr(100)
	request.Offset = common.Int64Ptr(0)
	response, err := client.DescribeProducts(request)
	if err != nil {
		return
	}
	for _, row := range response.Response.Products {
		list = append(list, *row.Name)
	}
	return
}

func (q *QCloudClient) RegionList() (list []RegionItem, err error) {
	cpf := profile.NewClientProfile()
	cpf.HttpProfile.Endpoint = "cvm.tencentcloudapi.com"
	client, _ := cvm.NewClient(q.Credential(), "", cpf)
	request := cvm.NewDescribeRegionsRequest()
	response, err := client.DescribeRegions(request)
	if err != nil {
		return
	}
	for _, val := range response.Response.RegionSet {
		list = append(list, RegionItem{
			Region:      *val.Region,
			RegionName:  *val.RegionName,
			RegionState: *val.RegionState,
		})
	}
	return
}

func (q *QCloudClient) ZoneList(region string) (list []ZoneItem, err error) {
	cpf := profile.NewClientProfile()
	cpf.HttpProfile.Endpoint = "cvm.tencentcloudapi.com"
	client, _ := cvm.NewClient(q.Credential(), region, cpf)
	request := cvm.NewDescribeZonesRequest()
	response, err := client.DescribeZones(request)
	if err != nil {
		return
	}
	for _, val := range response.Response.ZoneSet {
		list = append(list, ZoneItem{
			Zone:      *val.Zone,
			ZoneId:    *val.ZoneId,
			ZoneName:  *val.ZoneName,
			ZoneState: *val.ZoneState,
		})
	}
	return
}

type RegionItem struct {
	Region      string `json:"region,omitnil" name:"region"`
	RegionName  string `json:"regionName,omitnil" name:"regionName"`
	RegionState string `json:"regionState,omitnil" name:"regionState"`
}

type ZoneItem struct {
	Zone      string `json:"zone,omitnil" name:"zone"`
	ZoneName  string `json:"zoneName,omitnil" name:"zoneName"`
	ZoneId    string `json:"zoneId,omitnil" name:"zoneId"`
	ZoneState string `json:"zoneState,omitnil" name:"zoneState"`
}
